﻿using System;
using System.Web.Mvc;
using RanchBuddy.Core.Attributes;
using RanchBuddy.Core.DataAccess;
using RanchBuddy.Core.DataAccess.Impl;
using RanchBuddy.Core.Domain;
using RanchBuddy.Core.Domain.Impl;
using RanchBuddy.Core.Services;
using RanchBuddy.Core.Services.Impl;
using StructureMap;

namespace RanchBuddy.Web.Controllers
{

    [HandleError]
    public class AccountController : SmartController
    {
        public ActionResult ForgotPasswordSuccess()
        {
            return View();    
        }

        public ActionResult ForgotPassword()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult ForgotPassword(string Email, string Username)
        {
            ViewData["Email"] = Email;
            ViewData["Username"] = Username;

            // get password with email
            if (!string.IsNullOrEmpty(Email))
            {
                string password = ObjectFactory.GetInstance<IAccountService>().GetOpenPasswordByEmail(Email);
                if (!string.IsNullOrEmpty(password))
                {
                    EmailService.SendPasswordReminderEmail(Email, password); //success
                    return RedirectToAction<AccountController>(c => c.ForgotPasswordSuccess());
                }
            }

            // get password with username
            if (!string.IsNullOrEmpty(Username))
            {
                string password = ObjectFactory.GetInstance<IAccountService>().GetOpenPasswordByUsername(Username);
                if (!string.IsNullOrEmpty(password))
                {
                    //get the account by username so that we have an email address to work with!
                    IAccount a = ObjectFactory.GetInstance<IAccountService>().GetAccountByUsername(Username);
                    EmailService.SendPasswordReminderEmail(a.Email, password); //success
                    return RedirectToAction<AccountController>(c => c.ForgotPasswordSuccess());
                }
            }

            ModelState.AddModelError("_FORM", "A problem occured.  Please try again or contact us directly to assist you.");
            return View();
        }

        public ActionResult Index()
        {
            if (ObjectFactory.GetInstance<IWebContext>().Account != null)
                return RedirectToAction<AccountController>(c => c.EditAccount());
            else
                return RedirectToAction<AccountController>(c => c.LogOn());
        }

        public ActionResult LogOn()
        {

            return View();
        }

        [MustBeLoggedIn]
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult EditAccount()
        {
            IAccount a = ObjectFactory.GetInstance<IWebContext>().Account;
            return View(a);
        }

        [MustBeLoggedIn]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditAccount(FormCollection formValues)
        {
            IAccount a = ObjectFactory.GetInstance<IWebContext>().Account;
            UpdateModel(a);
            ObjectFactory.GetInstance<IAccountRepository>().SaveAccount(a);
            ObjectFactory.GetInstance<IWebContext>().Account = a;
            return View(a);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
        {
            ViewData["userName"] = userName;
            ViewData["password"] = password;
            ViewData["rememberMe"] = rememberMe;
            ViewData["returnUrl"] = returnUrl;

            IStatus s = ObjectFactory.GetInstance<IAccountService>().Login(userName, password, rememberMe);

            if (s.StatusType == Status.StatusTypes.Failure)
            {
                foreach (string m in s.GetMessages())
                {
                    ModelState.AddModelError("_FORM", m);
                }
            }
            else
            {
                if (!String.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction<HomeController>(c => c.Index());
                }
            }

            //if we get this far, there was an error.
            return View();
        }

        [MustBeLoggedIn]
        public ActionResult LogOff()
        {

            //clear the account from the session
            IStatus s = ObjectFactory.GetInstance<IAccountService>().Logout();

            return RedirectToAction<AccountController>(c=>c.LogOn());
        }

        public ActionResult VerifyEmailAccount(string ID)
        {
            bool result = ObjectFactory.GetInstance<IAccountRepository>().KeyExists(new Guid(ID));
            if (result)
                return RedirectToAction<AccountController>(c => c.VerifyEmailAccountSuccess());
            else
                return RedirectToAction<AccountController>(c => c.VerifyEmailAccountFailed());
        }

        public ActionResult VerifyEmailAccountSuccess()
        {
            return View();
        }

        public ActionResult VerifyEmailAccountFailed()
        {
            return View();
        }

        public ActionResult Register()
        {
            Term t = TermsRepository.GetLatestTerms();
            ViewData["TermID"] = t.TermID;
            ViewData["Terms"] = t.Terms;
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Register(string firstName, string lastName, string zipCode, 
            string homePhone, string workPhone, string cellPhone, string userName, string email, 
            string password, string confirmPassword, string secretQuestion, string secretAnswer, 
            string termID, string terms, string agreeWithTerms, string captcha, string birthDate, 
            string website)
        {
            ViewData["firstName"] = firstName;
            ViewData["lastName"] = lastName;
            ViewData["zipCode"] = zipCode;
            ViewData["homePhone"] = homePhone;
            ViewData["workPhone"] = workPhone;
            ViewData["cellPhone"] = cellPhone;
            ViewData["userName"] = userName;
            ViewData["email"] = email;
            ViewData["password"] = password;
            ViewData["confirmPassword"] = confirmPassword;
            ViewData["secretQuestion"] = secretQuestion;
            ViewData["secretAnswer"] = secretAnswer;
            ViewData["termID"] = termID;
            ViewData["terms"] = terms;
            ViewData["agreeWithTerms"] = agreeWithTerms;
            ViewData["birthDate"] = birthDate;
            ViewData["website"] = website;

            //check to see if the captcha matches
            if (ObjectFactory.GetInstance<IWebContext>().CaptchaImageText != captcha)
                ModelState.AddModelError("_FORM", HelpMessageService.GetHelpMessageBodyByID(13));
            //does the password match the confirm password?
            if (password != confirmPassword)
                ModelState.AddModelError("password", HelpMessageService.GetHelpMessageBodyByID(14));
            //does the password meet length regulations
            if (!(password.Length >= ConfigurationService.GetMinimumPasswordLength()) ||
                !(password.Length <= ConfigurationService.GetMaximumPasswordLength()))
                ModelState.AddModelError("password", HelpMessageService.GetHelpMessageBodyByID(3));
            //does the password meet complexity rebulations
            if (ValidationService.ValidatePasswordComplexity(password))
                ModelState.AddModelError("password", HelpMessageService.GetHelpMessageBodyByID(4));

            if(ModelState.IsValid)
            {
                //let's actually collect the data and stash it in the db
                IAccount a = new Account();
                a.Email = email;
                a.FirstName = firstName;
                a.LastName = lastName;
                a.Zipcode = zipCode;
                a.HomePhone = homePhone;
                a.CellPhone = cellPhone;
                a.WorkPhone = workPhone;
                a.SecretQuestion = secretQuestion;
                a.SecretAnswer = secretAnswer;
                a.Username = userName;
                a.Password = Cryptography.Encrypt(password,
                                                  ConfigurationService.Salt);
                a.TermID = Convert.ToInt32(termID);
                a.CreateDate = DateTime.Now;
                a.UpdateDate = DateTime.Now;
                a.EmailVerified = false;
                a.Website = website;
                a.Birthdate = Convert.ToDateTime(birthDate);

                //send email verification
                Guid g = Guid.NewGuid();
                a.VerificationKey = g;

                IStatus s = ObjectFactory.GetInstance<IAccountService>().SaveAccount(a);

                EmailService.SendRegistrationEmail(a.Email, g);


                if (s.StatusType == Status.StatusTypes.Failure)
                {
                    //any public errors?
                    foreach (string m in s.GetMessages())
                    {
                        ModelState.AddModelError("_FORM", m);
                    }
                    //any rule violations?
                    foreach (RuleViolation v in s.GetRuleViolations())
                    {
                        ModelState.AddModelError(v.PropertyName, v.ErrorMessage);
                    }
                }
                else
                {
                    return RedirectToAction<AccountController>(c => c.RegisterSuccess());
                }
            }

            return View();
        }

        public ActionResult RegisterSuccess()
        {
            return View();
        }

        [MustBeLoggedIn]
        public ActionResult ChangePassword()
        {

            //min password length

            return View();
        }

        [MustBeLoggedIn]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult ChangePassword(string currentPassword, string newPassword, string confirmPassword)
        {
            try
            {
                if (ObjectFactory.GetInstance<IAccountService>().ChangePassword(ObjectFactory.GetInstance<IWebContext>().Account, currentPassword, newPassword, confirmPassword).StatusType == Status.StatusTypes.Success)
                {
                    return RedirectToAction<AccountController>(c => c.ChangePasswordSuccess());
                }
                else
                {
                    ModelState.AddModelError("_FORM", HelpMessageService.GetHelpMessageBodyByID(10));
                    return View();
                }
            }
            catch
            {
                ModelState.AddModelError("_FORM", HelpMessageService.GetHelpMessageBodyByID(10));
                return View();
            }
        }

        public ActionResult ChangePasswordSuccess()
        {

            return View();
        }
    }
}
